home *** CD-ROM | disk | FTP | other *** search
/ 17 Bit Software 3: The Continuation / 17-Bit_The_Continuation_Disc.iso / amigan / amigan 7 / tracer / refract.c < prev    next >
C/C++ Source or Header  |  1994-01-27  |  5KB  |  291 lines

  1. #include <math.h>
  2. #include "MyMath.h"
  3. #include "rtd.h"
  4. #include "macros.h"
  5. #include "extern.h"
  6.  
  7. int    refract (r, bll)/*I've not been looking forward to commenting this
  8.               please excuse it if it is ugly. (if it was hard 
  9.               to write...)    */
  10. struct    ray    *r;
  11. struct    ball    *bll;
  12. {
  13.     struct    vector    new,
  14.             norm;
  15.     struct    mat    trans;
  16.     struct    ray    ir;
  17.     FFP     l,
  18.         refk (),
  19.         getcapt (),
  20.         capt,
  21.         inside ();
  22.     FFP    stupid;
  23.     struct    sphere    ss;
  24.  
  25. /* 
  26.     deal with a ray coming into the ball. figure out the normal,
  27.     and how much of the light is transmitted (capt)
  28. */
  29.  
  30.     SV (norm, r -> org, bll -> s.cent);
  31.     norm.l = LEN (norm);
  32.  
  33.     capt = getcapt (&norm, &(r -> dir), bll -> ior);
  34.  
  35.  
  36.     /* get the addition factor for the normal for refraction */
  37.     stupid = refk (&(norm), &(r -> dir), bll -> ior);
  38.     SCMLT (stupid, norm);
  39.  
  40.     AV (ir.dir, r -> dir, norm);
  41.     MV (r -> org.x, r -> org.y, r -> org.z, ir.org);
  42.  
  43.     /* now get it for reflection */
  44.     SV (norm, r -> org, bll -> s.cent);
  45.     norm.l = LEN (norm);
  46.     SCMLT (SPDiv(norm.l, SPFlt(1)), norm);
  47.     stupid = SPMul( SPFlt(2), DOT(norm, r -> dir) );
  48.     SCMLT (stupid, norm);
  49.     SV (r -> dir, r -> dir, norm);
  50.  
  51.     return (
  52.         SPFix(
  53.             SPAdd(
  54.                 SPMul(
  55.                     SPSub(
  56.                         capt,
  57.                         SPFlt(1)
  58.                     ),
  59.                     SPFlt(shade (r))
  60.                 ),
  61.                 SPMul(
  62.                     capt,
  63.                     inside (&ir, bll)
  64.                 )
  65.             )
  66.         )
  67.     );
  68. }
  69.  
  70. FFP    inside (r, bll)/* as above, except inside out. ior is 1.0/ior now */
  71. struct    ray    *r;
  72. struct    ball    *bll;
  73. {
  74.     struct    vector    new,
  75.             norm;
  76.     struct    mat    trans;
  77.     struct    ray    er;
  78.     FFP    findo (),
  79.         lght,
  80.         l,
  81.         refk (),
  82.         getcapt (),
  83.         capt,
  84.         stupid;
  85.     struct    sphere    ss;
  86.  
  87.  
  88.     if (++level < RLEV) {
  89.         r -> dir.l = LEN (r -> dir);
  90.         r -> dir.xzl = XZL (r -> dir);
  91.         mt (&(r -> dir), &trans);
  92.         ss.rad = bll -> s.rad;
  93.         SV (ss.cent, bll -> s.cent, r -> org);
  94.  
  95.         l = findo (&trans, &ss);
  96.         MV (SPMul(l, trans.x.x),SPMul(l, trans.x.y),SPMul(l, trans.x.z),new);
  97.         AV (er.org, r -> org, new);
  98.         AV (r -> org, r -> org, new);
  99.         SV (norm, er.org, bll -> s.cent);
  100.  
  101.         norm.l = LEN (norm);
  102.         r -> dir.l = LEN (r -> dir);
  103.         capt = getcapt (&norm, &(r -> dir),
  104.                 SPDiv(bll -> ior, SPFlt(1) )
  105.         );
  106.  
  107.         stupid = refk (&norm, &(r -> dir),
  108.                 SPDiv(bll -> ior, SPFlt(1) )
  109.         );
  110.  
  111.         SCMLT (stupid, norm);
  112.         AV (er.dir, norm, r -> dir);
  113.  
  114.         SV (norm, r -> org, bll -> s.cent);
  115.         norm.l = LEN (norm);
  116.         SCMLT ( SPDiv( norm.l, SPFlt(1) ), norm);
  117.         stupid = SPMul( SPFlt(2), DOT (norm, r -> dir) );
  118.         SCMLT (stupid, norm);
  119.         SV (r -> dir, r -> dir, norm);
  120.         lght =     SPAdd(
  121.                 SPMul(
  122.                     ( SPSub(capt, SPFlt(1) ) ),
  123.                     inside (r, bll)
  124.                 ),
  125.                 SPMul(
  126.                     capt,
  127.                     SPFlt( shade (&er) )
  128.                 )
  129.             );
  130. /*
  131.         lght = (1.0 - capt) * inside (r, bll) + (capt * (double) shade (&er));
  132. */
  133.     } else
  134.         lght = SPFlt(0);
  135.  
  136.     level--;
  137.  
  138.     return (lght);
  139. }
  140.  
  141.  
  142.  
  143. FFP    refk (nrm, in, ior)/*gets amount of normal that has to be added to
  144.                  incident ray to get the proper angle of
  145.                  refraction by ancient mystical methods */
  146. struct    vector    *nrm,
  147.         *in;
  148. FFP    ior;
  149. {
  150.     FFP    dt,
  151.         ln,
  152.         li,
  153.         ret;
  154.  
  155.     ior = SPMul(ior, ior);
  156.     dt = DOT ((*nrm), (*in));
  157.     ln = LN2 ((*nrm));
  158.     li = LN2 ((*in));
  159.  
  160.     if (SPTst(dt) < 0)
  161.         ret =    SPDiv(
  162.               ln,
  163.               SPSub(
  164.                 SPSqrt(
  165.                   SPSub(
  166.                     SPMul(
  167.                       dt,
  168.                       dt
  169.                     ),
  170.                     SPMul(
  171.                       ln, 
  172.                       SPMul(
  173.                          li,
  174.                         SPSub(
  175.                           ior,
  176.                           SPFlt(1)
  177.                         )
  178.                       )
  179.                     )
  180.                   )
  181.                 ),
  182.                 SPNeg(dt) 
  183.               )
  184.             );
  185. /*
  186.         ret = (-dt - sqrt (dt * dt - ln * li * (1 - ior))) / ln;
  187. */
  188.     else
  189.         ret =    SPDiv(
  190.               ln,
  191.               SPAdd(
  192.                 SPSqrt(
  193.                   SPSub(
  194.                     SPMul(
  195.                       dt,
  196.                       dt
  197.                     ),
  198.                     SPMul(
  199.                       ln, 
  200.                       SPMul(
  201.                          li,
  202.                         SPSub(
  203.                           ior,
  204.                           SPFlt(1)
  205.                         )
  206.                       )
  207.                     )
  208.                   )
  209.                 ),
  210.                 SPNeg(dt) 
  211.               )
  212.             );
  213. /*
  214.         ret = (-dt + sqrt (dt * dt - ln * li * (1 - ior))) / ln;
  215. */
  216.  
  217.     return (ret);
  218. }
  219.  
  220. FFP    getcapt (nrm, dr, ior)/* gets amount of light transmitted 
  221.                  through ball by mystical methods mentioned
  222.                  above. (see nasty physics text for details)*/
  223. struct    vector    *nrm,
  224.         *dr;
  225. FFP    ior;
  226. {
  227.     FFP    dt,
  228.         cs1,
  229.         cs2,
  230.         p,
  231.         s;
  232.  
  233.     dt = DOT ((*nrm), (*dr));
  234.     dt =     SPDiv(
  235.             LN2 ((*dr)),
  236.             SPDiv(
  237.                 LN2 ((*nrm)),
  238.                 SPMul(
  239.                     dt,
  240.                     dt
  241.                 )
  242.             )
  243.         );
  244.  
  245.     cs1 =    SPSqrt (dt);
  246.     cs2 =    SPSqrt (
  247.             SPSub(
  248.                 SPDiv(
  249.                     ior,
  250.                     SPSub(
  251.                         dt,
  252.                         SPFlt(1)
  253.                     )
  254.                 ),
  255.                 SPFlt(1)
  256.             )
  257.         );
  258.  
  259.     p = SPDiv(
  260.         SPAdd(
  261.             SPMul(
  262.                 ior,
  263.                 cs2
  264.             ),
  265.             cs1
  266.         ),
  267.         cs1
  268.     );
  269.  
  270.     s = SPDiv(
  271.         SPAdd(
  272.             SPMul(
  273.                 ior,
  274.                 cs1
  275.             ),
  276.             cs2
  277.         ),
  278.         cs1
  279.     );
  280.  
  281.     return (
  282.         SPMul(
  283.             SPFlt(2),
  284.             SPAdd(
  285.                 SPMul(p, p),
  286.                 SPMul(s, s)
  287.             )
  288.         )
  289.     );
  290. }
  291.